[TDR Generic表][C++ SDK]插入单条数据

1. 接口说明

向数据库表中插入一条记录(example路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/insert)

2. 版本要求

无特殊要求,所有版本都提供了该接口。

3. 准备工作

参见准备工作文档,完成使用该接口前的准备工作,并创建如下TDR Generic表,并使用TDR工具将XML表转换为C++代码。PLAYERONLINECNT表描述文件table_test.xml

<?xml version="1.0" encoding="GBK" standalone="yes" ?>
<metalib name="tcaplus_tb" tagsetversion="1" version="1">
<struct name="PLAYERONLINECNT" version="1" primarykey="TimeStamp,GameSvrID" splittablekey="TimeStamp">
    <entry name="TimeStamp"         type="uint32"     desc="单位为分钟" />
    <entry name="GameSvrID"         type="string"     size="64" />
    <entry name="GameAppID"         type="string"     size="64" desc="gameapp id" />
    <entry name="OnlineCntIOS"      type="uint32"     defaultvalue="0" desc="ios在线人数" />
    <entry name="OnlineCntAndroid"  type="uint32"     defaultvalue="0" desc="android在线人数" />
    <entry name="BinaryLen"         type="smalluint" defaultvalue="1" desc="数据来源数据长度;长度为0时,忽略来源检查"/>
    <entry name="binary"            type="tinyint"     desc="二进制" count= "1000" refer="BinaryLen" />
    <entry name="binary2"           type="tinyint"     desc="二进制2" count= "1000" refer="BinaryLen" />
    <entry name="strstr"            type="string"     size="64" desc="字符串"/>
    <index name="index_id"  column="TimeStamp"/>
</struct>
</metalib>

准备工作完成后,将会获得以下信息,这些信息在使用SDK时会被用到:

  1. 目录服务器地址列表
  2. 业务ID
  3. 业务访问密码
  4. 游戏区ID
  5. 数据表名

4. 示例代码

4.1 异步调用示例代码

示例代码的基本执行过程:

  1. 定义表配置参数
  2. 创建日志句柄;
  3. 创建客户端;
  4. 发送请求;
  5. 处理响应;
  6. 销毁客户端。
  7. 异步框架;

第1,2,3,6,7步是所有示例的通用代码,重点关注第4步和第5步,发送请求和处理响应

4.1.1 定义数据库表配置参数(代码路径:examples/tcaplus/C++_common_for_tdr1.0/common.h)

主要设置表的相关配置参数,在代码文件的头部

// 目标业务的tcapdir地址
static const char DIR_URL_ARRAY[][TCAPLUS_MAX_STRING_LENGTH] =
{
   "tcp://10.191.***.99:9999",
   "tcp://10.191.***.88:9999"
};
// 目标业务的tcapdir 地址个数
static const int32_t DIR_URL_COUNT = 2;

// 目标业务的集群ID
static const int32_t APP_ID = 3;
// 目标业务的表格组ID
static const int32_t ZONE_ID = 1;
// 目标业务的业务密码
static const char * SIGNATURE = "*******";
// 目标业务的表名 PLAYERONLINECNT
static const char * TABLE_NAME = "PLAYERONLINECNT";

4.1.2 创建日志句柄(代码路径:examples/tcaplus/C++_common_for_tdr1.0/common.h)

通过日志配置文件tlogconf.xml创建日志句柄,用于SDK的日志打印

//TCaplus service 日志类
TcaplusService::TLogger* g_pstTlogger;
LPTLOGCATEGORYINST g_pstLogHandler;
LPTLOGCTX g_pstLogCtx;
int32_t InitLog()
{
    // 日志配置文件的绝对路径
    const char* sLogConfFile = "tlogconf.xml";
    // 日志类名
    const char* sCategoryName = "mytest";
    //从配置文件初始化日志句柄
    g_pstLogCtx = tlog_init_from_file(sLogConfFile);
    if (NULL == g_pstLogCtx)
    {
        fprintf(stderr, "tlog_init_from_file failed.\n");
        return -1;
    }
    // 获取日志类
    g_pstLogHandler = tlog_get_category(g_pstLogCtx, sCategoryName);
    if (NULL == g_pstLogHandler)
    {
        fprintf(stderr, "tlog_get_category(mytest) failed.\n");
        return -2;
    }
    // 初始化日志句柄
    g_pstTlogger = new TcaplusService::TLogger(g_pstLogHandler);
    if (NULL == g_pstTlogger)
    {
        fprintf(stderr, "TcaplusService::TLogger failed.\n");
        return -3;
    }
    return 0;`
}

4.1.3 创建SDK客户端(代码路径:examples/tcaplus/C++_common_for_tdr1.0/common.h)

通过该代码创建一个Tcaplus客户端,该客户端只允许单线程使用,多线程模型可以在每个线程上初始化一个客户端实例

//Tcaplus service API的客户端主类
TcaplusService::TcaplusServer g_stTcapSvr;
//表的meta信息
extern unsigned char g_szMetalib_tcaplus_tb[];
LPTDRMETA g_szTableMeta = NULL;
int32_t InitServiceAPI()
{
    // 初始化
    int32_t iRet = g_stTcapSvr.Init(g_pstTlogger, /*module_id*/0, /*app id*/APP_ID, /*zone id*/ZONE_ID, /*signature*/SIGNATURE);
    if (0 != iRet)
    {
        tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.Init failed, iRet: %d.", iRet);
        return iRet;
    }

    // 添加目录服务器
    for (int32_t i = 0; i< DIR_URL_COUNT; i++)
    {
        iRet = g_stTcapSvr.AddDirServerAddress(DIR_URL_ARRAY[i]);
        if (0 != iRet)
        {
            tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.AddDirServerAddress(%s) failed, iRet: %d.", DIR_URL_ARRAY[i], iRet);
            return iRet;
        }
    }

    // 取得表的meta描述
    g_szTableMeta = tdr_get_meta_by_name((LPTDRMETALIB)g_szMetalib_tcaplus_tb, TABLE_NAME);
    if(NULL == g_szTableMeta)
    {
        tlog_error(g_pstLogHandler, 0, 0,"tdr_get_meta_by_name(%s) failed.", TABLE_NAME);
        return -1;
    }

    // 注册数据库表(连接dir服务器,认证,获取表路由),10s超时
    iRet = g_stTcapSvr.RegistTable(TABLE_NAME, g_szTableMeta, /*timeout_ms*/10000);
    if(0 != iRet)
    {
        tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.RegistTable(%s) failed, iRet: %d.", TABLE_NAME, iRet);
        return iRet;
    }

    // 连接表对应的所有tcaplus proxy服务器
    iRet = g_stTcapSvr.ConnectAll(/*timeout_ms*/10000, 0);
    if(0 != iRet)
    {
        tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.ConnectAll failed, iRet: %d.", iRet);
        return iRet;
    }

    return 0;
}

4.1.4 发送请求(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/insert/main.cpp)

创建请求,并且添加记录,使用客户端发送请求

/*
    用户缓存,返回的res应答将携带此缓存返回
    用户缓存由用户自己定义,缓存空间最大在tcaplus_protocol_cs.xml里边已经定义
    缓存空间最大为TCAPLUS_MAX_USERBUFF_LEN=1024字节
*/
typedef struct
{
    char m_szUserMessage[128];
    int32_t m_dwMagicNo;
    //...   
}TB_USERBUFFER;

int32_t SendInsertRequest(int32_t dwKey)
{
    // 请求对象类
    TcaplusService::TcaplusServiceRequest* pstRequest = g_stTcapSvr.GetRequest(TABLE_NAME);
    if (NULL == pstRequest)
    {
        tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.GetRequest(%s) failed.", TABLE_NAME);
        return -1;
    }
    int32_t iRet = pstRequest->Init(TCAPLUS_API_INSERT_REQ, NULL, 0, 0, 0, 0);
    if(0 != iRet)
    {
        tlog_error(g_pstLogHandler, 0, 0, "pstRequest->Init(TCAPLUS_API_INSERT_REQ) failed, iRet: %d.", iRet);
        return iRet;
    }

    // 设置用户自定义信息, 本例设置了m_dwMagicNo为当前请求的dwKey,和g_mapKeyTime结合做超时控制。m_szUserMessage由用户自己定义。
    TB_USERBUFFER stUserBuffer;
    stUserBuffer.m_dwMagicNo = dwKey;
    snprintf(stUserBuffer.m_szUserMessage, sizeof(stUserBuffer.m_szUserMessage), "%s", "user defined message");
    pstRequest->SetUserBuff((const char*)&stUserBuffer, sizeof(stUserBuffer)); 

    // 设置异步事务ID, 本例ullAsyncID设置为2, 实际使用时请参照实际情况, 主要用于异步并发时包的控制
    uint64_t ullAsyncID = 2;
    pstRequest->SetAsyncID(ullAsyncID);

    // 设置响应标志。主要用于Generic表的insert、increase、replace、update、delete操作和list表的单个delete操作。
    // iResultFlag  请求标志。0标志只需返回成功与否,1标志返回同请求一致的值,2标志返回操作后所有字段的值,3标志返回操作前所有字段的值
    char iResultFlag = 2;
    pstRequest->SetResultFlag(iResultFlag);

    TcaplusService::TcaplusServiceRecord* pstRecord = pstRequest->AddRecord();
    if (NULL == pstRecord)
    {
        tlog_error(g_pstLogHandler, 0, 0, "pstRequest->AddRecord() failed.");
        return -1;
    }

    PLAYERONLINECNT stPLAYERONLINECNT;
    memset(&stPLAYERONLINECNT, 0, sizeof(stPLAYERONLINECNT));

    // 设置查询的key信息
    stPLAYERONLINECNT.dwTimeStamp = dwKey;
    snprintf(stPLAYERONLINECNT.szGameSvrID, sizeof(stPLAYERONLINECNT.szGameSvrID), "%s", "mysvrid");

    // 设置更新的value信息
    snprintf(stPLAYERONLINECNT.szGameAppID, sizeof(stPLAYERONLINECNT.szGameAppID), "%s", "myappid");
    stPLAYERONLINECNT.dwOnlineCntIOS = 1;
    stPLAYERONLINECNT.dwOnlineCntAndroid = 1;

    // 设置基于TDR描述设置record数据
    iRet = pstRecord->SetData(&stPLAYERONLINECNT, sizeof(stPLAYERONLINECNT));
    if(0 != iRet)
    {
        tlog_error(g_pstLogHandler, 0, 0, "pstRecord->SetData() failed, iRet: %d.", iRet);
        return iRet;
    }  

    // 发送请求消息包
    iRet = g_stTcapSvr.SendRequest(pstRequest);
    if(0 != iRet)
    {
        tlog_error(g_pstLogHandler, 0, 0, "g_stTcapSvr.SendRequest failed, iRet: %d.", iRet);
        return iRet;
    }
    return 0;
}

4.1.5 处理响应(代码路径:examples/tcaplus/C++_tdr1.0_asyncmode_generic_simpletable/SingleOperation/insert/main.cpp)

处理响应,判断响应的返回值做响应处理,返回成功则从响应中获取记录

// 响应处理函数
int32_t HandleResponse(TB_USERBUFFER *pstUserBuffer, TcaplusServiceResponse* pstTcapRspRcved)
{
    if(NULL == pstTcapRspRcved || NULL == pstUserBuffer)
    {
        tlog_error(g_pstLogHandler, 0, 0, "NULL == pstTcapRspRcved || NULL == pstUserBuffer");
        return -1;
    }

    // 用户可以通过GetResult等接口获得返回的信息,其它接口参见头文件
    const char* pszTableName = pstTcapRspRcved->GetTableName();
    int32_t dwCmd = pstTcapRspRcved->GetCmd();
    int32_t dwResult = pstTcapRspRcved->GetResult();
    // 操作失败
    if( 0 != dwResult)
    {   
        tlog_error(g_pstLogHandler, 0, 0, "GetResult is not zero. dwResult: %d .", dwResult);
        // 记录不存在
        if (TcaplusService::ERR_RECORD_NOT_EXIST == dwResult)
        {
            tlog_error(g_pstLogHandler, 0, 0, "The TimeStamp = [%d] GameSvrID = [mysvrid], record is not exist. ", pstUserBuffer->m_dwMagicNo);
        }
        if (TcaplusService::ERR_TIME_OUT == dwResult)
        {
            HandleTimeoutResponse(pstUserBuffer->m_dwMagicNo);
        }
        if (TcaplusService::ERR_RECORD_EXIST == dwResult)
        {
            tlog_error(g_pstLogHandler, 0, 0, "key = [%d]  record is  exist. ", pstUserBuffer->m_dwMagicNo);
        }
        return -2;
    }    
    // 处理response包, 这里需要根据响应包做分包处理逻辑
    return HandleInsert(pstTcapRspRcved);
}

// 超时处理函数
int32_t HandleTimeoutResponse(int32_t dwKey)
{
    tlog_error(g_pstLogHandler, 0, 0, "The TimeStamp = [%d] GameSvrID = [mysvrid], response is timeout. ", dwKey);
    //处理超时的其它逻辑
    return 0;
}

//处理insert响应消息
int32_t HandleInsert(TcaplusServiceResponse* pstTcapRspRcved)
{
    if(NULL == pstTcapRspRcved)
    {
        return -1;
    }

    // 一个res包里包含的记录数
    int32_t dwRecordCount = pstTcapRspRcved->GetRecordCount();//获取结果中记录的条数
    const TcaplusServiceRecord * pstTcapRecord = NULL;
    int32_t dwCount = 0;
    // 循环读取记录数
    while(dwCount++ < dwRecordCount)
    {
      int32_t iRet = pstTcapRspRcved->FetchRecord(pstTcapRecord);
      if(0 != iRet || NULL == pstTcapRecord)
      {
        tlog_error(g_pstLogHandler, 0, 0, "FetchRecord failed, iRet: %d.", iRet);
        continue;
      }

      PLAYERONLINECNT stPLAYERONLINECNT;
      memset(&stPLAYERONLINECNT, 0, sizeof(stPLAYERONLINECNT));
      // 获得基于TDR描述的record数据
      iRet = pstTcapRecord->GetData(&stPLAYERONLINECNT, sizeof(stPLAYERONLINECNT));
      if(0 != iRet)
      {
        tlog_error(g_pstLogHandler, 0, 0, "GetData failed, iRet: %d .", iRet);
        return -4;
      }

      printf("----------Total record num %d ,the [%d] record is:\n", dwRecordCount, dwCount);
      printf("dwTimeStamp: %d \n", stPLAYERONLINECNT.dwTimeStamp);
      printf("szGameSvrID: %s \n", stPLAYERONLINECNT.szGameSvrID);
      printf("szGameAppID: %s \n", stPLAYERONLINECNT.szGameAppID);
      printf("dwOnlineCntIOS: %d \n", stPLAYERONLINECNT.dwOnlineCntIOS);
      printf("dwOnlineCntAndroid: %d \n", stPLAYERONLINECNT.dwOnlineCntAndroid);
    }
    return 0;
}

4.1.6 销毁客户端(代码路径:examples/tcaplus/C++_common_for_tdr1.0/common.h)

进程退出时,先调用客户端的Fini函数,销毁客户端,再销毁日志句柄,防止客户端退出时打日志coredump

void  Finish()
{
    //先销毁客户端
    g_stTcapSvr.Fini();
    tlog_info(g_pstLogHandler, 0, 0, "mytest finish!");
    //再销毁日志句柄
    delete g_pstTlogger;
    g_pstTlogger = NULL;
    tlog_fini_ctx(&g_pstLogCtx);
}

4.1.7 example异步框架(代码路径:examples/tcaplus/C++_common_for_tdr1.0/common.h)

通过实现回调函数的三个函数指针,proc主框架会调用相应的函数发送请求,接收响应和超时处理,该框架所有例子通用

// 函数回调机制
struct tagCallbackFunctions
{
    // 发送请求
    int (*pfnSendRequest)(int32_t key);
    // 接收响应
    int (*pfnHandResponse)(TB_USERBUFFER* pstUserBuffer, TcaplusServiceResponse* pstTcapRspRcved);
    // 超时处理
    int (*pfnHandTimeOutResponse)(int32_t dwKey);
};
typedef struct tagCallbackFunctions CALLBACK_FUNCTIONS;
CALLBACK_FUNCTIONS g_stCallbackFunctions;

int32_t main(int32_t argc, char *argv[])
{
    int32_t iRet = 0;
    // 初始化
    iRet = Init();
    if (0 != iRet)
    {
        tlog_error(g_pstLogHandler, 0, 0, "Init failed, iRet: %d, please check the mytest.log for detail. ", iRet);
        return iRet;
    }    

    // 下面设置回调函数
    g_stCallbackFunctions.pfnSendRequest = SendInsertRequest;
    g_stCallbackFunctions.pfnHandResponse =  HandleResponse;
    g_stCallbackFunctions.pfnHandTimeOutResponse = HandleTimeoutResponse;

    // 处理逻辑
    iRet = Proc();
    if (0 != iRet)
    {
        tlog_error(g_pstLogHandler, 0, 0, "Mytest failed, iRet: %d, please check the mytest.log for detail. ", iRet);
    }  

    // 清理环境
    Finish();
    return iRet;
}

int32_t Init()
{
    int32_t iRet = 0;
    // 初始化日志
    iRet = InitLog();
    if (0 != iRet)
    {
        return iRet;
    }
    // 初始化客户端
    iRet = InitServiceAPI();
    if (0 != iRet)
    {
        return iRet;
    }
    return iRet;
}

#define TIME_MS_PER_SEC 1000
static int TOTAL_SEND_RECV_NUM = 5; // 循环发送请求的次数,可以更改此值来发送多个请求
#define TCAPLUS_TIMEOUT_MS 10 * TIME_MS_PER_SEC // 发送req以后接收res包的超时时间,单位毫秒
#define TCAPLUS_SLEEEP_US 1000 // Proc一轮循环等待时间,单位微秒
std::map<int32_t,struct timeval> g_mapKeyTime; // Map二元组分别为发送数据的Key和发送时间
// 异步主处理框架
int32_t Proc()
{
    int32_t iRet = 0;
    // 本例子中使用变量iSendRequestCount是控制发包的数量
    int32_t iSendRequestCount = 0;
    while(true)
    {
        int32_t iKey = iSendRequestCount;
        // 异步发送多个请求
        if (iSendRequestCount < TOTAL_SEND_RECV_NUM)
        {
            if(NULL == g_stCallbackFunctions.pfnSendRequest)
            {
                tlog_error(g_pstLogHandler, 0, 0, "g_stCallbackFunctions.pfnSendRequest is NULL, so will finish example.");
                break;
            }
            iRet = (*g_stCallbackFunctions.pfnSendRequest)(iKey);
            if (0 != iRet)
            {
                tlog_error(g_pstLogHandler, 0, 0, "SendRequest failed, iRet: %d .", iRet);
                break;
            }
            // 添加时间戳,用于超时判断
            struct timeval now = {0};
            gettimeofday(&now, NULL);
            g_mapKeyTime[iKey] = now;
            iSendRequestCount++;
        }

        // 接收并处理包
        iRet = RecvPackage();
        if (0 != iRet)
        {
            tlog_error(g_pstLogHandler, 0, 0, "RecvPackage failed, iRet: %d .", iRet);
            break;
        }    

        // 判断发送的请求对应的回包是否有超时的现象。如果接收到响应包的时间超过了TIME_MS_PER_SEC,表示超时,将此key从g_mapKeyTime删除掉。
        struct timeval now = { 0 };
        gettimeofday(&now, NULL);
        std::map<int32_t, struct timeval>::iterator iter;
        for (iter = g_mapKeyTime.begin(); iter != g_mapKeyTime.end();)
        {
            int32_t iTotalUseTime = now.tv_sec * TIME_MS_PER_SEC + now.tv_usec / TIME_MS_PER_SEC - iter->second.tv_sec * TIME_MS_PER_SEC - iter->second.tv_usec / TIME_MS_PER_SEC;
            if (iTotalUseTime > TCAPLUS_TIMEOUT_MS)
            {
                tlog_debug(g_pstLogHandler, 0, 0, "RecvPackage timeout, key is %d iTotalUseTime = %d ", iter->first, iTotalUseTime);
                // 超时处理
                (*g_stCallbackFunctions.pfnHandTimeOutResponse)(iter->first);
                g_mapKeyTime.erase(iter++);
            }
            else
            {
                iter++;
            }
        }

        // 如果所有的包发送完毕,并且所有的包都处理完毕,则跳出循环,结束Proc()
        if (iSendRequestCount == TOTAL_SEND_RECV_NUM && 0 == g_mapKeyTime.size())
        {
            tlog_info(g_pstLogHandler, 0, 0, "All response is handle , so this test will finish. for more detail to read mytest.log!");
            break;
        }

        // 其它的工作...
        usleep(TCAPLUS_SLEEEP_US);
    }
    return iRet;
}

#define MAX_HANDLE_COUNTER_ONBUSY 1000
// 接收响应包
int32_t RecvPackage()
{
    uint32_t    dwHandleCnter = 0;
    uint32_t    dwMaxHandleCnter = MAX_HANDLE_COUNTER_ONBUSY;

    // 当本次循环次数达到MAX_HANDLE_COUNTER_ONBUSY仍然没有接收到TOTAL_SEND_RECV_NUM的响应包时,退出接收包的循环。
    // 尽量循环多次收包,防止本地积攒过多回包没有处理使Api本地缓存过满,从而proxy无法发包给Api,导致丢包。
    while (dwHandleCnter++ < dwMaxHandleCnter)
    {
        // warning 该函数返回的response指针是全局共用的,所以使用后请勿手动调用response->Destruct或者delete response。
        TcaplusServiceResponse* pstTcapRspRcved = NULL;

        // 接收响应包
        int32_t iRet = g_stTcapSvr.RecvResponse(pstTcapRspRcved);
        if (iRet < 0)
        {
            //失败,打印对应的错误码。
            tlog_debug(g_pstLogHandler, 0, 0, "g_stTcapSvr.RecvResponse failed, iRet: %d.", iRet);
        }
        else
        {
            // iRet == 1 成功,收到1个完整的响应包,此时输出参数response为非NULL指针。
            if(1 == iRet && NULL != pstTcapRspRcved)
            {
                TB_USERBUFFER *pstUserBuffer = NULL;
                const char  *sTmpUserBuffer = NULL;
                size_t      iTmpUserBuffSize;
                // 提取用户自定义数据,如果发包设置了UserBuff,则回包必须有UserBuff,否则出错
                sTmpUserBuffer = pstTcapRspRcved->GetUserBuff(&iTmpUserBuffSize);
                if(NULL == sTmpUserBuffer)
                {
                    tlog_error(g_pstLogHandler, 0, 0, "GetUserBuff failed ! ");
                    continue;
                }
                pstUserBuffer = (TB_USERBUFFER*)sTmpUserBuffer;
                if(NULL == pstUserBuffer)
                {
                    tlog_error(g_pstLogHandler, 0, 0, "GetUserBuff failed ! ");
                    continue;
                }

                // 从map中查找是否有key对应的记录,如果有,表示当前key的请求没有超时;没有表示超时。分别进入不同的逻辑。
                int32_t dwKey = pstUserBuffer->m_dwMagicNo;
                std::map<int32_t, struct timeval>::iterator it;
                it = g_mapKeyTime.find(dwKey);
                if (it != g_mapKeyTime.end())
                {
                    if(NULL == g_stCallbackFunctions.pfnHandResponse)
                    {
                        tlog_error(g_pstLogHandler, 0, 0, "g_stCallbackFunctions.pfnHandResponse is NULL, so will skip this package.");
                    }
                    else
                    {
                        // 删除Map对应Key的记录
                        g_mapKeyTime.erase(dwKey);
                        // 处理回包
                        (*g_stCallbackFunctions.pfnHandResponse)(pstUserBuffer, pstTcapRspRcved);
                    }
                }
                else
                {
                    if(NULL == g_stCallbackFunctions.pfnHandTimeOutResponse)
                    {
                        tlog_error(g_pstLogHandler, 0, 0, "g_stCallbackFunctions.pfnHandTimeOutResponse is NULL, so will skip this package.");
                    }
                    else
                    {
                        tlog_error(g_pstLogHandler, 0, 0, "This Key = [%d] is time out, so don't handle it!", dwKey);
                    }
                }
            }
            else
            {
                // iRet == 0 成功,但未收到完整的响应包。
                tlog_debug(g_pstLogHandler, 0, 0, "this loop not recieve a complete package!");
                break;
            }
        }
    }
    return 0;
}

5. 请求对象(request)中的方法说明

注:此处未列出请求对象的其它方法,即表示该方法在查询数据的场景不需要使用,误用可能会导致报错

    /**
    @brief 重置请求数据,以便用于下一次请求准备
    @param [IN]    cmd            请求操作类型,具体参见 \link TCaplusApiCmds \endlink
    @param [IN]    user_buffer    用户自定义信息缓冲区,作为异步信息携带给服务端,回包时原样返回
    @param [IN]    buffer_data_size     自定义缓冲区中的数据大小,支持的最大长度未1024
    @param [IN]    async_id       请求对应的异步事务ID,tcaplus会将其值不变地通过请求对应的响应消息带回来
    @param [IN]    seq             请求消息序列号,目前Tcaplus不会在Service Api侧将请求消息序列号做自动加1操作,tcaplus在服务器端也不会处理此消息序列号值,tcaplus会将此值不变地通过请求对应的响应消息带回来
    @param [IN]    result_flag    响应标志.该参数的含义和"int SetResultFlag(IN char result_flag)"中参数IN char result_flag的含义是相同的。
    @retval 0    成功
    @retval <0   失败,返回对应的错误码。
    @note    user_buffer参数中保存的自定义数据最大长度为1024
    */
    int Init(IN TCaplusApiCmds cmd,
        IN const char* user_buffer = NULL, IN const size_t buffer_data_size = 0, IN uint64_t async_id = 0,
        IN int32_t seq = 0, IN char result_flag = 0);

    /**
    @brief  获取请求操作类型
    @retval TCAPLUS_API_INVALID_REQ  未初始化时,返回此无效命令号。
    @retval \link TCaplusApiCmds \endlink
    */
    TCaplusApiCmds GetCmd() const;

    /**
    @brief    获取请求操作的表名
    @param [OUT] table_name_size      若table_name_size不为NULL,则向其所指位置写入表名长度。
    @retval NULL  TcaplusServiceRequest对象未初始化时返回NULL。
    @retval !NULL 指向操作的表名的指针。
    */
    const char* GetTableName(OUT size_t* table_name_size = NULL) const;

    /**
    @brief  获取请求操作的游戏区ID
    @retval 操作游戏区ID
    */
    int GetZoneId() const;

    /**
    @brief  设置用户缓存,应答将携带返回
    @param [IN] user_buffer      用户缓存指针
    @param [IN] buffer_data_size 用户缓存长度,支持的最大长度为1024字节
    @retval 0    设置成功
    @retval <0   失败,返回对应的错误码。
    */
    int SetUserBuff(IN const char* user_buffer, IN const size_t buffer_data_size);

    /**
    @brief    获取请求中的用户缓存信息
    @param    [OUT] buffer_data_size    若buffer_data_size不为NULL,则向其所指位置写入表名长度。
    @retval NULL  当TcaplusServiceRequest对象未初始化时返回NULL。
    @retval !NULL 用户缓存的首指针。
    */
    const char* GetUserBuff(OUT size_t* buffer_data_size = NULL) const;

    /**
    @brief  设置请求对应的异步事务ID。
    @param  [IN] async_id  请求对应的异步事务ID,tcaplus会将其值不变地通过请求对应的响应消息带回来
    @retval 0    设置成功
    @retval <0   失败,返回对应的错误码。
    */
    int SetAsyncID(IN uint64_t async_id);

    /**
    @brief  获取请求异步事务ID
    @retval 异步事务ID
    */
    uint64_t GetAsynID() const;

    /**
    @brief  设置请求序列号
    @retval 0    设置成功
    @retval <0   失败,返回对应的错误码。通常因为未初始化。
    */
    int SetSequence(IN int32_t seq);

    /**
    @brief  获取请求序列号
    @retval 请求序列号
    */
    int32_t GetSequence() const;

    /**
    @brief   获取请求的通用标志位
    @return  返回请求的通用标志位
    @note   有效的标志位列表及详细解释请参考 SetFlags()
    */
    int32_t GetFlags() const;

    /**
    @brief  向请求中添加一条记录。
    @param [IN] index    用于List操作,通常>=0,表示该Record在所属List中的Index(非下标)。
            用于List表中的TCAPLUS_API_LIST_ADDAFTER_REQ,TCAPLUS_API_LIST_ADDAFTER_BATCH_REQ, index可以取值TCAPLUS_API_LIST_PRE_FIRST_INDEX或TCAPLUS_API_LIST_LAST_INDEX命令号。
            index是辅助key,tcaplus会自动维护其唯一性,新插入的记录index会往上自增。
            当cmd是TCAPLUS_API_LIST_ADDAFTER_REQ时,表示记录插入在该index所在的记录之后(隐含约束:index对应的记录必须已存在);
            此时index还支持以下特殊值:
                        TCAPLUS_API_LIST_PRE_FIRST_INDEX:新元素插入在第一个元素之前
                       TCAPLUS_API_LIST_LAST_INDEX:新元素插入在最后一个元素之后
            对于Generic操作,index无意义将被忽略。
    @retval \link TcaplusRecord \endlink   返回记录指针
    @retval NULL     添加记录失败
    */
    TcaplusServiceRecord* AddRecord(IN int32_t index = -1);

    /**
    @brief  可视化输出请求
    @param [INOUT] buffer          缓冲区指针
    @param [IN] buffer_size     缓冲区大小
    @retval 打包的缓冲区指针,内容以'\0'结尾
    */
    const char* Print(INOUT char* buffer, IN size_t buffer_size);

    /**
    @brief  获取最后一次记录的错误信息。只有初始化logger参数为NULL时,request才会自动生成该缓冲区;否则会自动写日志,本函数返回NULL。
    @retval 最后错误信息缓冲区。
    */
    const char* GetLastError();

    /**
    @brief 设置需要查询或更新的Value字段名称列表,即部分Value字段查询和更新,
             可用于get, batchget, partkeyget, listget, listgetall, listreplace, replace, update, tabletraverse操作。
    @param [IN] field_name    需要查询或更新的字段名称列表,每个字段名称不超过32字节,名称以'\0'结尾
    @param [IN] field_count   字段名称个数
    @retval 0                 设置成功
    @retval <0                设置失败,具体错误参见 \link ErrorCode \endlink
    @note 当在更新操作(replace, batchReplace, update, batchUpdate, listreplace操作)中使用SetData()函数设置数据时,
        使用SetData()函数设置数据时,如果只需要更新部分字段,可以使用该
        函数设定需要更新的字段,但是,注意,在进行部分字段更新时,一
        定要先调用SetData()函数,然后再调用SetFieldNames()函数,这样才能达到部分
        部分字段更新的功能。

    @note 注意,在使用该函数设置字段名时,字段名只能包含value字段名,不能包含key字段名
    */
    int32_t SetFieldNames(IN const char* field_name[], IN const unsigned field_count);

    /**
    @brief 设置需要查询的Value字段名称,即部分Value字段查询,
             可用于get, batchget, partkeyget, listget, listgetall操作。
    @param [IN] field_name   添加的需要查询的字段名称,每个字段名称不超过32字节,名称以'\0'结尾
    @retval 0                设置成功
    @retval <0               设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t AddFieldName(IN const char* field_name);

    /**
    @brief  设置请求的通用标志位,可以通过"按位或"操作同时设定多个值
    @param  [IN]  flag. 请求标志位的值
    @retval 0     设置成功
    @retval <0    失败,返回对应的错误码。通常因为未初始化。
    @note   有效的标志位包括:
    *  TCAPLUS_FLAG_FETCH_ONLY_IF_MODIFIED:
    *       "数据变更才取回"标志位。在发起读操作之前,用户代码通过 TcaplusServiceRecord::SetVersion()
    *       带上本地缓存数据的版本号,并将此标志置位,那么存储端检测到当前数据与API本地缓存的数据版本
    *       一致时,表明该记录未发生过修改,API缓存的数据是最新的,因此在响应中将不会携带实际的数据,
    *       只是返回 TcapErrCode::COMMON_INFO_DATA_NOT_MODIFIED 的错误码
    *
    *       在请求中设置了此标志位之后,收到响应后应首先通过 TcaplusServiceResponse::GetFlags() 来获知
    *       发送请求时是否设置了TCAPLUS_FLAG_FETCH_ONLY_IF_MODIFIED标志.
    *
    *       只有如下请求支持设置此标志:
    *           TCAPLUS_API_GET_REQ,
    *           TCAPLUS_API_LIST_GET_REQ,
    *           TCAPLUS_API_LIST_GETALL_REQ
    *
    *  TCAPLUS_FLAG_FETCH_ONLY_IF_EXPIRED:
    *       "数据过期才取回"标志位。在发起读操作之前,用户代码通过 SetExpireTime() 设定数据过期时间,
    *       并将此标志置位,那么存储端若检测到记录在指定时间内发生过更新,则将数据返回,
    *       否则不返回实际数据,只是返回 TcapErrCode::COMMON_INFO_DATA_NOT_MODIFIED 的错误码。
    *
    *       在请求中设置了此标志位之后,收到响应后应首先通过 TcaplusServiceResponse::GetFlags() 来获知
    *       发送请求时是否设置了 TCAPLUS_FLAG_FETCH_ONLY_IF_EXPIRED 标志.
    *
    *       只有如下请求支持设置此标志:
    *           TCAPLUS_API_BATCH_GET_REQ
    *
    *  TCAPLUS_FLAG_ONLY_READ_FROM_SLAVE
    *       设置此标志后,读请求将会直接发送给Tcapsvr Slave 节点。
    *       Tcapsvr Slave 通常比较空闲,设置此标志有助于充分利用Tcapsvr Slave 资源。
    *
    *       适用场景:
    *                              对于数据实时性要求不高的读请求,
    *                              包括generic表和list表的所有读请求以及batchget,遍历请求
    *
    *  TCAPLUS_FLAG_LIST_RESERVE_INDEX_HAVING_NO_ELEMENTS
    *       设置此标志后,List表删除最后一个元素时需要保留index和version。
    *       ListDelete ListDeleteBatch ListDeleteAll操作在删除list表最后一个元素时,
    *          设置此标志在写入新的List记录时,版本号依次增长,不会被重置为1。
    *
    *       适用场景:
    *                              业务需要确定某个表在删除最后一个元素时是否需要保留index和version
    *                              主要涉及List表的使用体验
    *
    */
    int SetFlags(int32_t flag);

    /**
    @brief  清理请求的通用标志位,可以通过"按位或"操作同时设定多个值
    @param  [IN]  flag. 请求标志位的值
    @retval 0     设置成功
    @retval <0    失败,返回对应的错误码。通常因为未初始化。
    @note   有效的标志位列表及详细解释请参考 SetFlags()
    */
    int ClearFlags(int32_t flag);

    /**
    @brief  设置响应标志。主要用于Generic表的insert、increase、replace、update、delete操作和list表的单个delete replace操作。
    @param  [IN] result_flag  请求标志:
                                0表示: 只需返回操作执行成功与否
                                1表示: 返回与请求字段一致
                                2表示: 须返回变更记录的所有字段最新数据
                                3表示: 须返回变更记录的所有字段旧数据
    @retval 0    设置成功
    @retval <0   失败,返回对应的错误码。通常因为未初始化。
    @note 如果使用该接口,部分请求标志实际上是不支持的,强烈建议使用SetResultFlagForSuccess接口和SetResultFlagForFail接口
    */
    int SetResultFlag(IN char result_flag);

    /**
    @brief    设置响应标志。主要是本次请求成功执行后返回给前端的数据

    result_flag 的取值范围如下:

     TCaplusValueFlag_NOVALUE = 0,              // 不返回任何返回值
     TCaplusValueFlag_SAMEWITHREQUEST = 1,      // 返回同请求一致的值
     TCaplusValueFlag_ALLVALUE = 2,           // 返回tcapsvr端操作后所有字段的值
     TCaplusValueFlag_ALLOLDVALUE = 3,          // 返回tcapsvr端操作前所有字段的值


    下面是各个支持的命令字在设置不同的result_flag下执行成功后返回给API端的数据详细情况:

     1. TCAPLUS_API_INSERT_REQ TCAPLUS_API_BATCH_INSERT_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回本次insert操作后的数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回空数据

     2. TCAPLUS_API_REPLACE_REQ TCAPLUS_API_BATCH_REPLACE_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回本次replace操作后的数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据, 如果tcapsvr端没有数据,即返回为空

     3. TCAPLUS_API_UPDATE_REQ TCAPLUS_API_BATCH_UPDATE_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回本次update操作后的数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据

     4. TCAPLUS_API_INCREASE_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回本次increase操作后的数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据, 如果tcapsvr端没有数据,即返回为空

     5. TCAPLUS_API_DELETE_REQ TCAPLUS_API_BATCH_DELETE_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回空数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据

     6. TCAPLUS_API_LIST_DELETE_BATCH_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据, 暂时没有实现
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据, 凡是本次成功删除的index对应的数据都会返回

     7. TCAPLUS_API_LIST_ADDAFTER_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据, 暂时没有实现
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后, 返回本次插入的记录和本次淘汰的数据记录
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后不返回数据

     8. TCAPLUS_API_LIST_DELETE_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据, 暂时没有实现
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回空数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端listdelete前的数据

     9. TCAPLUS_API_LIST_REPLACE_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 则操作成功后不返回数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据, 暂时没有实现
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回tcapsvr端listreplace后的数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端listreplace前的数据
    10. TCAPLUS_API_LIST_REPLACE_BATCH_REQ
         如果设置的是TCaplusValueFlag_NOVALUE, 操作成功后返回和请求一致的数据
         如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作成功后返回和请求一致的数据
         如果设置的是TCaplusValueFlag_ALLVALUE, 则操作成功后返回tcapsvr端listreplace后的数据
         如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端listreplace前的数据

     @param  [IN] result_flag  请求标志:
                                 0表示: 只需返回操作执行成功与否
                                 1表示: 返回与请求字段一致
                                 2表示: 须返回变更记录的所有字段最新数据
                                 3表示: 须返回变更记录的所有字段旧数据
     @retval 0      设置成功
     @retval <0   失败,返回对应的错误码。通常因为未初始化。

     */
    int SetResultFlagForSuccess (char result_flag);

    /**
    @brief    设置响应标志。主要是本次请求执行失败后返回给前端的数据

    result_flag 的取值范围如下:

    TCaplusValueFlag_NOVALUE = 0,             // 不返回任何返回值
    TCaplusValueFlag_SAMEWITHREQUEST = 1,     // 返回同请求一致的值
    TCaplusValueFlag_ALLVALUE = 2,             // 返回tcapsvr端操作后所有字段的值
    TCaplusValueFlag_ALLOLDVALUE = 3,         // 返回tcapsvr端操作前所有字段的值


   下面是各个支持的命令字在设置不同的result_flag下执行失败后返回给API端的数据详细情况:

    1. TCAPLUS_API_INSERT_REQ  TCAPLUS_API_BATCH_INSERT_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空

    2. TCAPLUS_API_REPLACE_REQ  TCAPLUS_API_BATCH_REPLACE_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空

    3. TCAPLUS_API_UPDATE_REQ  TCAPLUS_API_BATCH_UPDATE_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空

    4. TCAPLUS_API_INCREASE_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空

    5. TCAPLUS_API_DELETE_REQ TCAPLUS_API_BATCH_DELETE_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空

    6. TCAPLUS_API_LIST_DELETE_BATCH_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据, 暂时没有实现
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 则操作成功后返回tcapsvr端操作前的数据, 凡是本次成功删除的index对应的数据都会返回

    7. TCAPLUS_API_LIST_ADDAFTER_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据, 暂时没有实现
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 不返回数据

    8. TCAPLUS_API_LIST_DELETE_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据, 暂时没有实现
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空

    9. TCAPLUS_API_LIST_REPLACE_REQ
        如果设置的是TCaplusValueFlag_NOVALUE, 则操作失败后不返回数据
        如果设置的是TCaplusValueFlag_SAMEWITHREQUEST, 则操作失败后返回和请求一致的数据, 暂时没有实现
        如果设置的是TCaplusValueFlag_ALLVALUE, 不合理场景
        如果设置的是TCaplusValueFlag_ALLOLDVALUE, 如果获取到了tcapsvr端的数据则返回tcpasvr端的数据,如果没有获取到tcapsvr端的数据则返回空

    @param    [IN] result_flag  请求标志:
                                0表示: 只需返回操作执行成功与否
                                1表示: 返回与请求字段一致
                                2表示: 须返回变更记录的所有字段最新数据
                                3表示: 须返回变更记录的所有字段旧数据

    @retval 0     设置成功
    @retval <0     失败,返回对应的错误码。通常因为未初始化。

    */
    int SetResultFlagForFail (char result_flag);

    /**
    @brief  获取响应标志
    @return 返回响应标志
    */
    char GetResultFlag() const;

    /**
    @brief  获取响应标志, 主要是采用 SetResultFlagForSuccess设置的值
    @return 返回响应标志
    */
    char GetResultFlagForSuccess () const;

    /**
    @brief  获取响应标志, 主要是采用SetResultFlagForFail设置的值
    @return 返回响应标志
    */
    char GetResultFlagForFail () const;

6. 响应对象(response)中的方法说明

注:此处未列出的响应对象的其它方法,即表示该方法在查询数据的场景不需要使用,误用可能会导致报错

    /**
    @brief  获取请求操作的表名
    @param [OUT] table_name_size      若table_name_size不为NULL,则向其所指位置写入表名长度,
                                      该长度包括结尾的'\0'。
    @retval NULL  TcaplusServiceResponse对象未初始化时返回NULL。
    @retval !NULL 指向操作的表名的指针。
    */
    const char* GetTableName(OUT size_t* table_name_size = NULL) const;

    /** \brief  获取操作结果
    *  \retval 0             操作结果成功
    *  \retval >0            操作结果警告,例如Get或删除一个不存在的数据记录则retval为TcapErrCode::TXHDB_ERR_RECORD_NOT_EXIST,具体错误参见 \link ErrorCode \endlink
    *  \retval <0            操作结果错误,例如写数据失败则retval为TcapErrCode::SVR_ERR_FAIL_WRITE_RECORD,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetResult() const;

   /**
    @brief  获取APPID
    @retval 非0            返回响应包中的app_id
    @retval 0              当对象未初始化或尚未解析过响应包时,默认返回0
    */
    int64_t GetAppId() const;

   /**
    @brief  获取ZoneId
    @retval 非0            返回响应包中的zond_id
    @retval 0              当对象未初始化或尚未解析过响应包时,默认返回0
    */
    int GetZoneId() const;

    /**
    @brief  获取结果操作类型
    @retval \link TCaplusApiCmds \endlink
    */
    TCaplusApiCmds GetCmd() const;

    /**
    @brief  获取请求子操作类型,对document操作才有意义
    @retval \link TCaplusApiCmds \endlink
    */
    uint32_t GetSubCmd() const;

    /**
    @brief  获取结果异步事务ID
    @retval 异步事务ID
    */
    uint64_t GetAsynID() const;

    /**
    @brief  获取结果序列号
    @retval 响应序列号
    */
    int32_t GetSequence() const;

    /**
    @brief   获取响应的通用标志位
    @return  返回响应的通用标志位
    @note   有效的标志位列表及详细解释请参考 TcaplusServiceRequest::SetFlags(int)
    */
    int32_t GetFlags() const;

    /**
    @brief  获取响应中的用户缓存信息
    @param  [out] buffer_data_size  用户缓存数据大小,若buffer_data_size不为NULL,则向其所指位置写入用户缓存数据的长度。
    @retval NULL  当TcaplusServiceResponse对象未初始化时返回NULL。
    @retval !NULL 用户缓存的首指针。
    */
    const char* GetUserBuff(OUT size_t* buffer_data_size = NULL) const;

    /**
    @brief  获取本响应中结果记录条数
    @retval 本响应中结果记录条数
    */
    int32_t GetRecordCount() const;

    /**
    @brief  从结果中获取一条记录
    @param [OUT] 指向返回记录的指针
    @retval 0   获取记录成功
    @retval 非0     获取记录失败
    @note 通过此函数获取到本次操作的TcaplusServiceRecord对象后,上次操作获取到的TcaplusServiceRecord对象会被覆盖.
    */
   int32_t FetchRecord(OUT const TcaplusServiceRecord*& record);

    /**
    @brief  可视化输出
    @param [INOUT] buffer           缓冲区指针
    @param [IN] buffer_size      缓冲区大小
    @retval 打包的缓冲区指针,内容以'\0'结尾
    */
    const char* Print(INOUT char* buffer, IN size_t buffer_size);

7. 记录对象(record)中的方法说明

注:此处未列出的响应对象的其它方法,即表示该方法在查询数据的场景不需要使用,误用可能会导致报错

  • record的通用方法:

      /**
      @brief  设置记录版本号
      @param [IN] iVersion     数据记录的版本号:  <=0 表示不关注版本号不关心版本号。具体含义如下。
                  当class TcaplusServiceRequest的int SetCheckDataVersionPolicy(enum tagCHECKDATAVERSIONTYPE type)函数传入的参数type的值为CHECKDATAVERSION_AUTOINCREASE时: 表示检测记录版本号。如果class TcaplusServiceRecord的void SetVersion(IN int32_t iVersion)函数传入的参数iVersion的值<=0,则仍然表示不关心版本号不关注版本号;如果class TcaplusServiceRecord的void SetVersion(IN int32_t iVersion)函数传入的参数iVersion的值>0,那么只有当该版本号与服务器端的版本号相同时,Replace, Update, Increase, ListAddAfter, ListDelete, ListReplace, ListDeleteBatch操作才会成功同时在服务器端该版本号会自增1。
                  当class TcaplusServiceRequest的int SetCheckDataVersionPolicy(enum tagCHECKDATAVERSIONTYPE type)函数传入的参数type的值为NOCHECKDATAVERSION_OVERWRITE时: 表示不检测记录版本号。如果class TcaplusServiceRecord的void SetVersion(IN int32_t iVersion)函数传入的参数iVersion的值<=0,则会把版本号1写入服务端的数据记录版本号(服务器端成功写入的数据记录的版本号最少为1);如果class TcaplusServiceRecord的void SetVersion(IN int32_t iVersion)函数传入的参数iVersion的值>0,那么会把该版本号写入服务端的数据记录版本号。
                  当class TcaplusServiceRequest的int SetCheckDataVersionPolicy(enum tagCHECKDATAVERSIONTYPE type)函数传入的参数type的值为NOCHECKDATAVERSION_AUTOINCREASE时: 表示不检测记录版本号,将服务器端的数据记录版本号自增1,若服务器端新写入数据记录则新写入的数据记录的版本号为1。
      @retval void
      */
      //Attention, 注意,对于Generic操作表示设置Record的版本,对于List操作表示设置Record所在List单元的版本。
      void SetVersion(IN int32_t iVersion);
    
      /**
      @brief  获取记录版本号
      @retval 记录版本号
      @note 对于Generic操作表示获取Record的版本;对于List操作表示获取Record所在List的版本。
      */
      int32_t GetVersion() const;
    
      /**
      @brief  基于TDR描述设置record的过滤条件
      @param [IN] condition      条件语句
      @retval 0                  设置成功
      @retval <0                 设置失败,具体错误参见 \link ErrorCode \endlink
      */
      int32_t SetCondition(const std::string &condition);
    
      /**
      @brief  基于TDR描述设置record中数组的操作语句
      @param [IN] operation      操作语句,包括 PUSH / POP / SET / GET
      @param [IN] operateOption  操作选项,仅 GET 有用,见 enum RecordOperationOption
      @retval 0                  设置成功
      @retval <0                 设置失败,具体错误参见 \link ErrorCode \endlink
      */
      int32_t SetOperation(const std::string &operation, int operateOption = 0);
    
  • record可以基于TDR结构设置和提取记录

      /**
      @brief  基于TDR描述设置record数据
      @param [IN] data_buffer     数据缓冲区
      @param [IN] data_size       数据缓冲区大小
      @param [IN] data_version    数据版本号,参看SetVersion函数。默认值-1表示写操作时不校验版本号, 不关心版本号. data_version为<=0都表示写操作时不会校验版本号, 不关心版本号
      @param [IN] data_meta       数据缓冲区的数据对应的meta描述;NULL则自动使用request设置的默认meta信息,参看对应的SetTable函数。
      @param [IN] partkey_index_name  部分键查询的索引名称。
      @retval 0                  设置成功
      @retval <0                 设置失败,具体错误参见 \link ErrorCode \endlink
      */
      int32_t SetData(IN const void* data_buffer, IN size_t data_size,
          IN int32_t data_version = -1, IN LPTDRMETA data_meta = NULL,
          IN const char* partkey_index_name = NULL);
    
      /**
      @brief  基于TDR描述获取record数据
      @param [OUT] data_buffer    数据缓冲区;必须先通过 memset 或者 tdr_init 对其进行初始化
      @param [IN] data_size      数据缓冲区大小
      @param [OUT] data_version   数据版本号,参看GetVersion函数。
      @param [IN] data_meta       要取的数据对应的meta描述;NULL则自动使用response设置的默认meta信息,参看对应的SetTable函数。
      @retval 0                  设置成功
      @retval <0                 设置失败,具体错误参见 \link ErrorCode \endlink
      */
      int32_t GetData(OUT void* data_buffer, IN size_t data_buffer_size,
          OUT int32_t* data_version = NULL, IN LPTDRMETA data_meta = NULL) const;
    
  • record同时支持通过SetKey SetValue接口设置记录中的字段,通过GetKey GetValue接口提取记录中的字段,但是SetKey、SetValue、GetKey、GetValue同SetData、GetData接口不可混用

    1. SetKey SetValue接口设置的数据,只能通过GetKey,GetValue接口读取;SetKey SetValue在使用batch命令时需要注意,record设置完成后调用Pack()把记录打包;SetData是一次性的,函数调用会自动打包,而SetKey SetValue不确定用户什么时候设置完最后一个字段,所以需要用户设置完kv后调用Pack()把记录打包;
    2. SetData接口设置的数据,只能通过GetData读取
    /**
    @brief  通用的key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容,最大长度1024字节
    @param [IN] value_size           字段内容长度
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKey(IN const char* field_name, IN const void * field_value, IN const size_t value_size);

    /**
    @brief  int8_t类型key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKeyInt8(IN const char* field_name, IN const int8_t field_value);

    /**
    @brief  int16_t类型key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKeyInt16(IN const char* field_name, IN const int16_t field_value);

    /**
    @brief  int32_t类型key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKeyInt32(IN const char* field_name, IN const int32_t field_value);

    /**
    @brief  int64_t类型key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKeyInt64(IN const char* field_name, IN const int64_t field_value);

    /**
    @brief  float类型key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKeyFloat(IN const char* field_name, IN const float field_value);

    /**
    @brief  double类型key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKeyDouble(IN const char* field_name, IN const double field_value);

    /**
    @brief  string类型key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容,最大长度1024字节,以'\0'结尾
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKeyStr(IN const char* field_name, IN const char* field_value);

    /**
    @brief  blob类型key字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容,最大长度1024字节
    @param [IN] value_size           字段内容长度
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetKeyBlob(IN const char* field_name, IN const char* field_value, IN const size_t value_size);
    /**
    @brief  通用的value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容,最大长度128KB(Tcapsvr>=3.24.0时,最大长度支持256KB)
    @param [IN] value_size           字段内容长度
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValue(IN const char* field_name, IN const void * field_value, IN const size_t value_size);

    /**
    @brief  int8_t类型value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValueInt8(IN const char* field_name, IN const int8_t field_value);

    /**
    @brief  int16_t类型value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValueInt16(IN const char* field_name, IN const int16_t field_value);

    /**
    @brief  int32_t类型value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValueInt32(IN const char* field_name, IN const int32_t field_value);

    /**
    @brief  int64_t类型value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValueInt64(IN const char* field_name, IN const int64_t field_value);

    /**
    @brief  float类型value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValueFloat(IN const char* field_name, IN const float field_value);

    /**
    @brief  double类型value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValueDouble(IN const char* field_name, IN const double field_value);

    /**
    @brief  string类型value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB),以'\0'结尾
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValueStr(IN const char* field_name, IN const char* field_value);

    /**
    @brief  blob类型value字段内容设置
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [IN] field_value         字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB)
                                    注意:对于Blob,系统预留了2B用于版本号建设,因此,写入时数据不要超过(最大长度-2B)
    @param [IN] value_size          字段内容长度
    @retval 0                       设置成功
    @retval 非0                     设置失败,具体错误参见 \link ErrorCode \endlink
    */
    int SetValueBlob(IN const char* field_name, IN const char* field_value, IN const size_t value_size);
    /**
    @brief  通用的key字段内容获取
    @param  [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容,最大长度1024字节
    @param  [OUT] value_size         字段内容长度
    @retval 0                        获取成功
    @retval 非0                      获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKey(IN const char* field_name, OUT void *& field_value, OUT size_t & value_size) const;

    /**
    @brief  int8_t类型的key字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value       字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKeyInt8(IN const char* field_name, OUT int8_t & field_value) const;

    /**
    @brief  int16_t类型的key字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value       字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKeyInt16(IN const char* field_name, OUT int16_t & field_value) const;

    /**
    @brief  int32_t类型的key字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKeyInt32(IN const char* field_name, OUT int32_t & field_value) const;

    /**
    @brief  int64_t类型的key字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKeyInt64(IN const char* field_name, OUT int64_t & field_value) const;

    /**
    @brief  float类型的key字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKeyFloat(IN const char* field_name, OUT float & field_value) const;

    /**
    @brief  double类型的key字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKeyDouble(IN const char* field_name, OUT double & field_value) const;

    /**
    @brief  string类型的key字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param [OUT] field_value        字段内容,最大长度1024字节,以'\0'结尾
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKeyStr(IN const char* field_name, OUT const char*& field_value) const;

    /**
    @brief  blob类型的key字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容,最大长度1024字节
    @param  [OUT] value_size          字段内容长度
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKeyBlob(IN const char* field_name, OUT const char*& field_value, OUT size_t & value_size) const;

    /**
    @brief  key字段数目获取
    @retval 0                       Key字段(Key Field)数目
    */
    uint32_t GetKeyCount() const;

    /**
    @brief  key字段内容获取
    @param [IN] fieldIndex          字段下标,其有效值必须大于等于0并且小于GetKeyNum()
    @param  [OUT] field_name        字段名称,是字符串
    @param  [OUT] field_value        字段内容,最大长度1024字节
    @param  [OUT] value_size          字段内容长度
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetKey(IN uint32_t fieldIndex, OUT const char*& field_name, OUT const void *& field_value, OUT size_t& fieldValueLen) const;
    /**
    @brief  通用的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容,最大长度128K字节
    @param  [OUT] value_size          字段内容长度
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValue(IN const char* field_name, OUT void *& field_value, OUT size_t & value_size) const;

    /**
    @brief  int8_t类型的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValueInt8(IN const char* field_name, OUT int8_t & field_value) const;

    /**
    @brief  int16_t类型的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValueInt16(IN const char* field_name, OUT int16_t & field_value) const;

    /**
    @brief  int32_t类型的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValueInt32(IN const char* field_name, OUT int32_t & field_value) const;

    /**
    @brief  int64_t类型的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValueInt64(IN const char* field_name, OUT int64_t & field_value) const;

    /**
    @brief  float类型的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValueFloat(IN const char* field_name, OUT float & field_value) const;

    /**
    @brief  double类型的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValueDouble(IN const char* field_name, OUT double & field_value) const;

    /**
    @brief  string类型的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB),以'\0'结尾
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValueStr(IN const char* field_name, OUT const char*& field_value) const;

    /**
    @brief  blob类型的value字段内容获取
    @param [IN] field_name          字段名称,最大长度32字节,以'\0'结尾
    @param  [OUT] field_value        字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB)
    @param  [OUT] value_size          字段内容长度
    @retval 0                       获取成功
    @retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValueBlob(IN const char* field_name, OUT const char*& field_value, OUT size_t & value_size) const;

    /**
    @brief    Value字段数目获取
     *    \retval 0                        Value字段(Value Field)数目
    */
    uint32_t GetValueCount() const;

    /**
    @brief   Value字段内容获取
     *   \param [IN] fieldIndex            字段下标,其有效值必须大于等于0并且小于GetValueNum()
     *   \param  [OUT] field_name        字段名称,是字符串
     *   \param  [OUT] field_value        字段内容,最大长度128K字节(Tcapsvr>=3.24.0时,最大长度支持256KB)
     *   \param  [OUT] value_size            字段内容长度
     *   \retval 0                        获取成功
     *   \retval 非0                     获取失败,具体错误参见 \link ErrorCode \endlink
    */
    int32_t GetValue(IN int fieldIndex, OUT const char*& field_name, OUT const void *& field_value, OUT size_t& fieldValueLen) const;

8. 常见问题

详见错误码含义和处理方法

8. 其它参考文档

[TDR Generic表][Java SDK]插入单条数据接口说明

[TDR Generic表][Go SDK]插入单条数据接口说明

[TDR Generic表][MySQL协议兼容接口]插入数据接口说明

results matching ""

    No results matching ""